package com.jz.pay.pool;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

public class MyThreadPool {
    private final int core;
    private final int max;
    private final int queueCapacity = Integer.MAX_VALUE;
    ArrayDeque<Runnable> maxTaskList;
    ArrayList<MyTask> pool; // 核心线程
    AtomicInteger runs; // 核心线程执行任务中的有多少个
    AtomicInteger count = new AtomicInteger(0);// 汇总任务,总执行任务
    AtomicInteger rejet = new AtomicInteger(0);// 汇总任务,总拒绝任务

    public MyThreadPool(int core, int max){
        pool = new ArrayList<>(core);
        maxTaskList = new ArrayDeque<>(max);
        runs = new AtomicInteger(0);
        this.core = core;
        this.max = max;
        for (int i = 0; i < core; i++) {
            MyTask myTask = new MyTask(i,runs,this);
            pool.add(myTask);
            myTask.start();
        }
    }

    /**
     * 提交任务，不允许空
     * 放进任务队列。如果任务队列放不下了，新开线程执行，如果新开线程达到最大线程数，则拒绝
     * @param task
     */
    public void submit(Runnable task){
        if (task == null){
            System.out.println("不可提交空任务！");
            return;
        }
        if(runs.get()<core){
            for (int i = 0; i < core; i++) {
                MyTask myTask = pool.get(i);
                if(!myTask.isRunning()){
                    myTask.setTask(task);
                    myTask.invokeNotify();
                    return;
                }
            }
        }
        synchronized (maxTaskList){
            if(maxTaskList.size() < queueCapacity){
                maxTaskList.add(task);
            }else if(pool.size() < max){
                addTasker(task).start();
            }else{
                rejet.incrementAndGet();
                System.out.println("任务提交失败："+maxTaskList.size()+","+pool.size());
                return;
            }

        }
    }

    /**
     * 获取一个任务
     * @return
     */
    private Runnable getTask(){
        synchronized (maxTaskList){
            return maxTaskList.poll();
        }
    }
    private MyTask addTasker(Runnable task){
        MyTask myTask = new MyTask(pool.size()+Long.valueOf(System.currentTimeMillis()).intValue(),task,this);
        pool.add(myTask);
        return myTask;
    }
    protected void removeTasker(MyTask myTask){
        synchronized (pool){
            pool.remove(myTask);
        }
    }

    public static void main(String[] args) throws IOException {
        MyThreadPool pool = new MyThreadPool(9,16);
        for (int i = 0; i < 120; i++) {
            final int k = i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("      任务  "+k);
                }
            });
        }
//        BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
//        String userInputStr;
//        while ((userInputStr = userInput.readLine()) != null) {
//            String finalUserInputStr = userInputStr;
//            pool.submit(new Runnable() {
//                @Override
//                public void run() {
//                    System.out.println("      任务  "+ finalUserInputStr);
//                }
//            });
//        }
    }

    static class MyTask extends Thread{
        private final MyThreadPool myThreadPool;
        private final int num;
        private boolean core;
        private AtomicInteger runs;
        volatile private Runnable task;
        private boolean closed;

        private Boolean enable;

        MyTask(int num,Runnable task, MyThreadPool myThreadPool){
            this.task = task;
            this.num = num;
            this.myThreadPool = myThreadPool;
        }

        MyTask(int num, AtomicInteger runs,MyThreadPool myThreadPool){
            this.core = true;
            this.num = num;
            this.runs = runs;
            this.myThreadPool = myThreadPool;
        }

        public void invokeNotify(){
            if (this.enable == null){

            }else if (!this.enable){
                this.enable = true;
                synchronized (this){
//                    System.out.println(num+" 被唤醒");
                    this.notify();
                }
            }
        }
        public void invokeWait(){
            if (this.enable == null || this.enable){
                this.enable = false;
                try {
                    synchronized (this){
                        System.out.println(num+" 进入等待");
                        this.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 判断线程是否在执行任务
         * @return
         */
        public Runnable hasTask(){
            if (this.task != null){
                Runnable tar = this.task;
                this.task = null;
                return tar;
            }
            return myThreadPool.getTask();
        }

        /**
         * 是否是核心线程
         * @return
         */
        public boolean isCore(){
            return core;
        }

        public boolean isRunning(){
            return this.task != null;
        }
        public void setTask(Runnable task){
            this.task = task;
        }

        public void close(){
            closed = true;
            this.myThreadPool.removeTasker(this);
        }

        public boolean isClosed(){
            return closed;
        }
        public int incre(){
            if (core){
                return runs.getAndIncrement();
            }
            return 0;
        }
        public int decre(){
            if (core){
                return runs.getAndDecrement();
            }
            return 0;
        }

        /**
         * 判断线程存活时间，超过1秒则关闭
         * 判断当前是否存在任务，不存在则执行任务
         * 执行完任务将任务丢弃，重新设置线程开始时间
         */
        @Override
        public void run() {
//            System.out.println(num+" 线程等待任务中!");
            long start = System.currentTimeMillis();
            while (!isClosed()){
                if(this.enable != null && this.enable){
                    this.enable = null;
                    System.out.println(num+" 线程被唤醒...");
                    start = System.currentTimeMillis();
                }
                Runnable task;
                if(!isCore()&&System.currentTimeMillis()-start>1000){
                    close();
                }if(isCore()&&System.currentTimeMillis()-start>10000){
                    invokeWait();
                }else if(null != (task = hasTask())){
                    myThreadPool.count.incrementAndGet();
                    incre();
                    System.out.println(num+" 开始执行任务");
                    try {
                        task.run();
                    }catch (Exception e){
//                        System.out.println(num+" 执行错误");
                        e.printStackTrace();
                    }
                    start = System.currentTimeMillis();
//                    System.out.println(num+" 结束执行任务");
//                    System.out.println(num+" 线程再次等待任务中...");
                    decre();
                }
            }
            System.out.println(num+" 线程终止");
        }
    }
}
